package cn.lili.controller.order;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.lili.common.enums.DictCodeEnum;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.utils.SysDictUtils;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.member.entity.dos.Partner;
import cn.lili.modules.member.service.PartnerService;
import cn.lili.modules.order.aftersale.entity.dos.AfterSale;
import cn.lili.modules.order.aftersale.entity.vo.AfterSaleSearchParams;
import cn.lili.modules.order.aftersale.entity.vo.AfterSaleVO;
import cn.lili.modules.order.aftersale.service.AfterSaleService;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.enums.OrderItemAfterSaleStatusEnum;
import cn.lili.modules.order.order.service.OrderItemService;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.permission.entity.dos.AdminUser;
import cn.lili.modules.permission.service.AdminUserService;
import cn.lili.modules.store.entity.dto.StoreAfterSaleAddressDTO;
import cn.lili.modules.system.entity.vo.Traces;
import cn.lili.modules.wallet.service.MemberWalletService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * 管理端,售后接口
 *
 * @author Bulbasaur
 * @since 2021/1/6 14:11
 */
@RestController
@RequestMapping("/manager/afterSale")
@Api(tags = "管理端,售后接口")
public class AfterSaleManagerController {

	/**
	 * 售后
	 */
	@Autowired
	private AfterSaleService afterSaleService;
	@Autowired
	private AdminUserService adminUserService;
	@Autowired
	private PartnerService partnerService;

	@Autowired
	private OrderItemService orderItemService;

	@Autowired
	private MemberWalletService memberWalletService;

	@ApiOperation(value = "分页获取售后服务")
	@RequestMapping(value = "/page")
	public ResultMessage<IPage<AfterSaleVO>> getByPage(AfterSaleSearchParams searchParams) {
		AuthUser currentUser = UserContext.getCurrentUser();
		// 如果当前会员不为空，且为代理商角色
		if (currentUser != null && (currentUser.getRole().equals(UserEnums.AGENT))) {
			// AdminUser adminUser = adminUserService.getById(currentUser.getId());
			// if (null != adminUser) {
			// searchParams.setExtension(adminUser.getPromotionCode());
			// }
			// 查询合伙人区域
			LambdaQueryWrapper<Partner> lambdaQueryWrapper = new LambdaQueryWrapper<>();
			lambdaQueryWrapper.eq(Partner::getMemberId, currentUser.getMemberId());
			lambdaQueryWrapper.eq(Partner::getDeleteFlag, 0);
			lambdaQueryWrapper.eq(Partner::getPartnerState, 0);
			lambdaQueryWrapper.eq(Partner::getPartnerType, 4);
			Partner partner = partnerService.getOne(lambdaQueryWrapper);
			if (null != partner && StringUtils.isNotEmpty(partner.getRegionId())) {
				searchParams.setAdcode(partner.getRegionId());
			}
		}
		return ResultUtil.data(afterSaleService.getAfterSalePages(searchParams));
	}

	@ApiOperation(value = "获取导出售后服务列表列表")
	@RequestMapping(value = "/exportAfterSaleOrder")
	public ResultMessage<List<AfterSale>> exportAfterSaleOrder(AfterSaleSearchParams searchParams) {
		return ResultUtil.data(afterSaleService.exportAfterSaleOrder(searchParams));
	}

	@ApiOperation(value = "查看售后服务详情")
	@ApiImplicitParam(name = "sn", value = "售后单号", required = true, paramType = "path")
	@RequestMapping(value = "/get/{sn}")
	public ResultMessage<AfterSaleVO> get(@NotNull(message = "售后单号") @PathVariable("sn") String sn) {
		return ResultUtil.data(afterSaleService.getAfterSale(sn));
	}

	@ApiOperation(value = "查看买家退货物流踪迹")
	@ApiImplicitParam(name = "sn", value = "售后单号", required = true, paramType = "path")
	@RequestMapping(value = "/getDeliveryTraces/{sn}")
	public ResultMessage<Traces> getDeliveryTraces(@PathVariable String sn) {
		return ResultUtil.data(afterSaleService.deliveryTraces(sn));
	}

	@ApiOperation(value = "售后线下退款")
	@ApiImplicitParams({@ApiImplicitParam(name = "afterSaleSn", value = "售后sn", required = true, paramType = "path"),
			@ApiImplicitParam(name = "remark", value = "备注", paramType = "query")})
	@PutMapping(value = "/refund/{afterSaleSn}")
	public ResultMessage<AfterSale> refund(@NotNull(message = "请选择售后单") @PathVariable String afterSaleSn,
			@RequestParam String remark) {

		return ResultUtil.data(afterSaleService.refund(afterSaleSn, remark));
	}

	@ApiOperation(value = "审核售后申请")
	@ApiImplicitParams({@ApiImplicitParam(name = "afterSaleSn", value = "售后sn", required = true, paramType = "path"),
			@ApiImplicitParam(name = "serviceStatus", value = "PASS：审核通过，REFUSE：审核未通过", required = true, paramType = "query"),
			@ApiImplicitParam(name = "remark", value = "备注", paramType = "query"),
			@ApiImplicitParam(name = "actualRefundPrice", value = "实际退款金额", paramType = "query")})
	@PutMapping(value = "/review/{afterSaleSn}")
	public ResultMessage<AfterSale> review(@NotNull(message = "请选择售后单") @PathVariable String afterSaleSn,
			@NotNull(message = "请审核") String serviceStatus, String remark, Double actualRefundPrice) {
		String serviceStatusName = "";
		for (AfterSaleStatusEnum afterSaleStatusEnum : AfterSaleStatusEnum.values()) {
			if (serviceStatus.equals(afterSaleStatusEnum.name())) {
				serviceStatusName = afterSaleStatusEnum.description();
			}
		}
		return ResultUtil.data(
				afterSaleService.review(afterSaleSn, serviceStatus, serviceStatusName, remark, actualRefundPrice));
	}

	@ApiOperation(value = "获取商家售后收件地址")
	@ApiImplicitParam(name = "sn", value = "售后单号", required = true, paramType = "path")
	@RequestMapping(value = "/getStoreAfterSaleAddress/{sn}")
	public ResultMessage<StoreAfterSaleAddressDTO> getStoreAfterSaleAddress(
			@NotNull(message = "售后单号") @PathVariable("sn") String sn) {
		return ResultUtil.data(afterSaleService.getStoreAfterSaleAddressDTO(sn));
	}

	@ApiOperation(value = "订单完成后7天不允许售后申请,自动分佣")
	@RequestMapping("/closeAfterSale")
	@Scheduled(cron = "0 0 0 */1 * ?")
	public void closeAfterSale() {

		// 订单关闭售后申请时间 = 当前时间 - 自动关闭售后申请天数
		DateTime receiveTime = DateUtil.offsetDay(DateUtil.date(),
				-Integer.parseInt(SysDictUtils.getValueString(DictCodeEnum.AUTO_COMMISSION.dictCode())));

		// 关闭售后订单=未售后订单+小于订单关闭售后申请时间
		QueryWrapper queryWrapper = new QueryWrapper();
		queryWrapper.le("o.complete_time", receiveTime);
		queryWrapper.notIn("oi.after_sale_status", OrderItemAfterSaleStatusEnum.ALREADY_APPLIED.name(),
				OrderItemAfterSaleStatusEnum.EXPIRED.name());
		queryWrapper.eq("oi.merchandise_status", 0);
		List<OrderItem> orderItems = orderItemService.waitOperationOrderItem(queryWrapper);

		// 判断是否有符合条件的订单，关闭允许售后申请处理
		if (!orderItems.isEmpty()) {

			// 获取订单货物ID
			List<String> orderItemIdList = orderItems.stream().map(OrderItem::getId).collect(Collectors.toList());

			// 修改订单售后状态
			LambdaUpdateWrapper<OrderItem> lambdaUpdateWrapper = new LambdaUpdateWrapper<OrderItem>()
					.set(OrderItem::getAfterSaleStatus, OrderItemAfterSaleStatusEnum.EXPIRED.name())
					.in(OrderItem::getId, orderItemIdList);
			orderItemService.update(lambdaUpdateWrapper);
			// 自动分佣
			List<OrderItem> arrays = orderItems.stream()
					.collect(Collectors.collectingAndThen(
							Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(OrderItem::getOrderSn))),
							ArrayList::new));
			arrays.forEach(item -> {
				memberWalletService.confirmOrder(item.getOrderSn());
			});
		}
	}
}
